package com.cdream.basic.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author cdream
 * @date 2021/9/9
 */
public class NotifyWaitExample {
    public static void main(String[] args) {
        char[] char1 = "123456".toCharArray();
        char[] char2 = "abcdef".toCharArray();
        ReentrantLock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                for (char c : char1) {
                    System.out.println(c);
                    condition2.signal();
                    condition1.await();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "num");
        Thread t2 = new Thread(() -> {
            lock.lock();
            try {
                for (int i = 0; i < char2.length; i++) {
                    condition2.await();
                    System.out.println(char2[i]);
                    condition1.signal();
                }
                condition1.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "char");
        t2.start();
        t1.start();
    }

    private static void waitNotifyResolve(char[] char1, char[] char2) {
        Object lock = new Object();
        new Thread(() -> {
            synchronized (lock) {
                for (char c : char1) {
                    System.out.println(c);
                    try {
                        System.out.println("notify1+start");
                        lock.notify();
                        System.out.println("notify1+end");
                        Thread.sleep(1000);
                        System.out.println("wait1+start");
                        lock.wait();
                        System.out.println("wait1+end");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notify();
            }
        }).start();
        new Thread(() -> {
            synchronized (lock) {
                for (char c : char2) {
                    System.out.println(c);
                    try {
                        System.out.println("notify2+start");
                        lock.notify();
                        System.out.println("notify2+end");
                        Thread.sleep(1000);
                        System.out.println("wait2+start");
                        lock.wait();
                        System.out.println("wait2+end");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.notify();
            }
        }).start();
    }

}
